package visiopuce.DAO;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Query;

import visiopuce.HibernateUtil;
import visiopuce.objets.Personne;
import visiopuce.objets.Recherche;

public class PersonneDAOImpl extends GenericDAOImpl<Personne, BigDecimal> implements PersonneDAO {

	/** Constructeur priv� */
	private PersonneDAOImpl() {
	}

	/** Instance unique non pr�initialis�e */
	private static PersonneDAOImpl INSTANCE = null;

	/** Point d'acc�s pour l'instance unique du singleton */
	public static PersonneDAO getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new PersonneDAOImpl();
		}
		return INSTANCE;
	}

	public String[] getNomFromString(String debut) {
		List<String> noms = null;
		String sql = "SELECT distinct p.nom FROM Personne p WHERE p.nom LIKE :debut";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("debut", debut + "%");
		noms = query.list();
		return noms.toArray(new String[0]);
	}

	public String[] getNomPrenomFromString(String debut) {
		List<String> noms = null;
		String sql = "SELECT distinct concat(concat(concat(concat(p.nom,' # '), p.prenom),' # '),p.dateNaissance) FROM Personne p WHERE p.nom LIKE :debut";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("debut", debut + "%");
		noms = query.list();
		return noms.toArray(new String[0]);
	}

	public String[] getNomFromNomPrenom(String nom, String prenom) {
		List<String> noms = null;
		String sql = "SELECT distinct p.prenom FROM Personne p WHERE p.nom LIKE :nom and p.prenom LIKE :prenom";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("nom", nom + "%").setParameter("prenom", prenom + "%");

		noms = query.list();
		return noms.toArray(new String[0]);
	}

	// AJOUTER DATE DE NAISSANCE!!!

	public Personne getPersonneByNomPrenomDateNaissance(String nom, String prenom, Date dateNaissance) {
		Personne personne = null;
		String sql = "SELECT p FROM Personne p WHERE p.nom LIKE :nom and p.prenom LIKE :prenom and p.dateNaissance = :dateNaissance";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("nom", nom).setParameter("prenom", prenom).setParameter("dateNaissance", dateNaissance);
		List<Personne> personnes = findMany(query);
		if (personnes.size() > 0) {
			personne = personnes.get(0);
		}
		return personne;
	}

	public List<Personne> findAllByRecherche(Recherche recherche) {
		List<Personne> personnes = null;
		String sql = "SELECT distinct p FROM Resultat r right outer join r.analyse a right outer join a.prelevement t right outer join t.personne p  WHERE p.idPersonne is not null ";
		if (recherche.getNom() != null) {
			sql += " and p.nom like :nom ";
		}
		if (recherche.getPrenom() != null) {
			sql += " and p.prenom like :prenom ";
		}
		if (recherche.getNumeroHospit() != null) {
			sql += " and t.numSejour like :hospit";
		}

		if (recherche.getNumeroPrelevement() != null) {
			sql += " and t.numeroPrelevement like :numeroPrelevement ";
		}
		if (recherche.getSecteur() != null) {
			sql += " and t.secteur = :secteur ";
		}

		// sur l'analyse
		if (recherche.isQueUrgent()) {
			sql += " and a.urgent = :urgent  and r.resultat like :nonRendu ";
		}
		if (recherche.getQueRendu() >= 0) {
			if (recherche.getQueRendu() == 1) {
				sql += " and r.resultat not LIKE :nonRendu ";
			}
			if (recherche.getQueRendu() == 0) {
				sql += " and r.resultat LIKE :nonRendu ";
			}
		}
		if (recherche.getQueRecherche() >= 0) {
			if (recherche.getQueRecherche() == 1) {
				sql += " and t.recherche = true ";
			}
			if (recherche.getQueRecherche() == 0) {
				sql += " and t.recherche = false ";
			}
		}
		if (recherche.getQueDPI() >= 0) {
			if (recherche.getQueDPI() == 1) {
				sql += " and t.dpi = true ";
			}
			if (recherche.getQueDPI() == 0) {
				sql += " and t.dpi = false ";
			}
		}
		if (recherche.getBiomedecine() != null) {
			sql += " and t.indication = :indication ";
		}
		if (recherche.getPrescripteur() != null) {
			sql += " and t.prescripteur = :prescripteur ";
		}
		if (recherche.getSignataire() != null) {
			sql += " and r.signataire = :signataire ";
		}
		if (recherche.getTypeAnalyse() != null) {
			sql += " and a.typeAnalyse = :typeAnalyse ";
		}
		if (recherche.getTypePrelevement() != null) {
			sql += " and t.typePrelevement = :typePrelevement ";
		}
		if (recherche.getTypeRendu() != null) {
			sql += " and r.typeRendu = :typeRendu ";
		}
		if (recherche.getUfExec() != null) {
			sql += " and a.typeRendu LIKE :ufExec ";
		}
		if (recherche.getUfPresc() != null) {
			sql += " and a.typeRendu LIKE :ufPresc ";
		}
		if (recherche.getDateNaissanceDebut() != null) {
			sql += " and p.dateNaissance > :dateNaissanceDebut ";
		}
		if (recherche.getDatePrelevementDebut() != null) {
			sql += " and (t.datePrelevement > :datePrelevementDebut OR t.dateReception > :datePrelevementDebut2 )";
		}
		if (recherche.getDateResultatDebut() != null) {
			sql += " and r.dateRendu > :dateResultatDebut ";
		}
		if (recherche.getDateTechniqueDebut() != null) {
			sql += " and a.dateTechnique > :dateTechniqueDebut ";
		}
		if (recherche.getDateNaissanceFin() != null) {
			sql += " and p.dateNaissance < :dateNaissanceFin ";
		}
		if (recherche.getDatePrelevementFin() != null) {
			sql += " and (t.datePrelevement < :datePrelevementFin OR t.dateReception < :datePrelevementFin2 )";
		}
		if (recherche.getDateResultatFin() != null) {
			sql += " and r.dateRendu < :dateResultatFin ";
		}
		if (recherche.getDateTechniqueFin() != null) {
			sql += " and a.dateTechnique < :dateTechniqueFin ";
		}
		if (recherche.getResultat() != null) {
			sql += " and r.resultat LIKE :resultat ";
		}
		if (recherche.getChromosomes() != null && recherche.getChromosomes().size() > 0) {
			sql += " and (";
			int i = 0;
			for (String chr : recherche.getChromosomes()) {
				sql += "(r.chromosomes like '%|" + chr + "|%') or";
				sql += "(r.chromosomes like '" + chr + "|%') or ";
				sql += "(r.chromosomes like '%|" + chr + "')";
				if (i != recherche.getChromosomes().size() - 1) {
					sql += " or ";
				}
				i++;
			}
			sql += ")";
		}
		// private String chromosomes = null;

		// sql += "and t.personne = p and a.prelevement = t and r.analyse = a";
		Query query = HibernateUtil.getSession().createQuery(sql);
		if (recherche.getNom() != null) {
			query.setParameter("nom", recherche.getNom() + "%");
		}
		if (recherche.getPrenom() != null) {
			query.setParameter("prenom", recherche.getPrenom() + "%");
		}
		// numeroHospit
		if (recherche.getNumeroHospit() != null) {
			query.setParameter("hospit", recherche.getNumeroHospit());
		}

		// sur le prelévement
		if (recherche.getNumeroPrelevement() != null) {
			query.setParameter("numeroPrelevement", recherche.getNumeroPrelevement());
		}
		if (recherche.getSecteur() != null) {
			query.setParameter("secteur", recherche.getSecteur());
		}

		// sur l'analyse
		if (recherche.isQueUrgent()) {
			query.setParameter("urgent", recherche.isQueUrgent());
			query.setParameter("nonRendu", "Non rendu");
		}
		if (recherche.getQueRendu() >= 0) {
			query.setParameter("nonRendu", "Non rendu");
		}

		if (recherche.getBiomedecine() != null) {
			query.setParameter("indication", recherche.getBiomedecine());

		}
		if (recherche.getPrescripteur() != null) {
			query.setParameter("prescripteur", recherche.getPrescripteur());
		}
		if (recherche.getSignataire() != null) {
			query.setParameter("signataire", recherche.getSignataire());

		}
		if (recherche.getTypeAnalyse() != null) {
			query.setParameter("typeAnalyse", recherche.getTypeAnalyse());
		}
		if (recherche.getTypePrelevement() != null) {
			query.setParameter("typePrelevement", recherche.getTypePrelevement());
		}
		if (recherche.getTypeRendu() != null) {
			query.setParameter("typeRendu", recherche.getTypeRendu());
		}
		if (recherche.getUfExec() != null) {
			query.setParameter("ufExec", recherche.getUfExec());
		}
		if (recherche.getUfPresc() != null) {
			query.setParameter("ufPresc", recherche.getUfPresc());
		}
		if (recherche.getDateNaissanceDebut() != null) {
			query.setParameter("dateNaissanceDebut", recherche.getDateNaissanceDebut());
		}
		if (recherche.getDatePrelevementDebut() != null) {
			query.setParameter("datePrelevementDebut", recherche.getDatePrelevementDebut());
			query.setParameter("datePrelevementDebut2", recherche.getDatePrelevementDebut());
		}
		if (recherche.getDateResultatDebut() != null) {
			query.setParameter("dateResultatDebut", recherche.getDateResultatDebut());
		}
		if (recherche.getDateTechniqueDebut() != null) {
			query.setParameter("dateTechniqueDebut", recherche.getDateTechniqueDebut());
		}
		if (recherche.getDateNaissanceFin() != null) {
			query.setParameter("dateNaissanceFin", recherche.getDateNaissanceFin());
		}
		if (recherche.getDatePrelevementFin() != null) {
			query.setParameter("datePrelevementFin", recherche.getDatePrelevementFin());
			query.setParameter("datePrelevementFin2", recherche.getDatePrelevementFin());
		}
		if (recherche.getDateResultatFin() != null) {
			query.setParameter("dateResultatFin", recherche.getDateResultatFin());
		}
		if (recherche.getDateTechniqueFin() != null) {
			query.setParameter("dateTechniqueFin", recherche.getDateTechniqueFin());
		}
		if (recherche.getResultat() != null) {
			query.setParameter("resultat", recherche.getResultat());
		}
		personnes = findMany(query);
		return personnes;
	}

	public Personne numSejourUnique(String numSejour, Integer idPersonne) {
		Personne personne = null;
		String sql = "SELECT p FROM Personne p WHERE p.idPersonne != :idPersonne and p.numSejour LIKE :numSejour";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPersonne", idPersonne).setParameter("numSejour", numSejour);
		personne = findOne(query);
		return personne;
	}

	public Personne ippUnique(String numIPP, Integer idPersonne) {
		Personne personne = null;
		String sql = "SELECT p FROM Personne p WHERE p.idPersonne != :idPersonne and p.iPP LIKE :iPP";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPersonne", idPersonne).setParameter("iPP", numIPP);
		personne = findOne(query);
		return personne;
	}

	public ArrayList<Personne> nomUnique(String nom, Integer idPersonne) {
		ArrayList<Personne> personnes = null;
		String sql = "SELECT p FROM Personne p WHERE p.idPersonne != :idPersonne and p.nom LIKE :nom";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPersonne", idPersonne).setParameter("nom", nom);
		personnes = (ArrayList<Personne>) findMany(query);
		return personnes;
	}

	public ArrayList<Personne> nomPrenomUnique(String nom, String prenom) {
		ArrayList<Personne> personnes = null;
		String sql = "SELECT p FROM Personne p WHERE p.prenom LIKE :prenom and p.nom LIKE :nom";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("prenom", prenom).setParameter("nom", nom);
		personnes = (ArrayList<Personne>) findMany(query);
		return personnes;
	}

	@Override
	public int getIdPersonneFromPuce(int idPuce) {
		String sql = "SELECT  p.analyse.prelevement.personne.idPersonne FROM Puce p WHERE p.idPuce = :idPuce";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPuce", idPuce);
		int r = (int) query.uniqueResult();
		return r;
	}

	@Override
	public int getIdPersonneFromPrelevement(int idPrelevement) {
		String sql = "SELECT  p.personne.idPersonne FROM Prelevement p WHERE p.idPrelevement = :idPrelevement";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPrelevement", idPrelevement);
		int r = (int) query.uniqueResult();
		return r;
	}

	@Override
	public int getIdPersonneFromAnalyse(int idAnalyse) {
		String sql = "SELECT  p.prelevement.personne.idPersonne FROM Analyse p WHERE p.idAnalyse = :idAnalyse";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idAnalyse", idAnalyse);
		int r = (int) query.uniqueResult();
		return r;
	}

	@Override
	public int getIdPersonneFromResultat(int idResultat) {
		String sql = "SELECT  p.analyse.prelevement.personne.idPersonne FROM Resultat p WHERE p.idResultat = :idResultat";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idResultat", idResultat);
		int r = (int) query.uniqueResult();
		return r;
	}

	@Override
	public int getIdPersonneFromAlteration(int idAlteration) {
		String sql = "SELECT  p.puce.analyse.prelevement.personne.idPersonne FROM Alteration p WHERE p.idAlteration = :idAlteration";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idAlteration", idAlteration);
		int r = (int) query.uniqueResult();
		return r;
	}

	@Override
	public String getSexeByIdPuce(Integer idPuce) {
		String sexe = null;
		String sql = "SELECT  p.analyse.prelevement.personne.sexe FROM Puce p WHERE p.idPuce = :idPuce";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPuce", idPuce);
		sexe = (String) query.uniqueResult();
		return sexe;
	}

	@Override
	public List<Object[]> getPeronneAPasserPuceFromString(String debut) {
		List<Object[]> objects = new ArrayList<Object[]>();
		String sql = "SELECT distinct a.prelevement.numeroPrelevement, a.prelevement.personne.nom, " + "a.prelevement.personne.prenom,  a.idAnalyse , a.urgent , a.prelevement.typePrelevement.libelle "
				+ "FROM Puce p right outer join p.analyse a WHERE a.typeAnalyse.idTypeAnalyse = 3 AND a.prelevement.personne.nom " + "LIKE :debut AND a.dateTechnique is null " + " AND (p is null or (p.dateScan is null" + " AND p.dateAnnotation is null" + " AND p.dateRelecture is null"
				+ " AND p.dateReunion is null AND p.conclusionReunion is null " + "AND p.commentaireAnnotateur is null and p.parametres is null )) order by a.prelevement.dateReception ";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("debut", debut + "%");
		objects = (List<Object[]>) query.list();

		return objects;
	}

	@Override
	public Object[] getPeronneAPasserPuceFromIdPuce(int idPuce) {
		Object[] objects = null;
		String sql = "SELECT distinct p.analyse.prelevement.numeroPrelevement, p.analyse.prelevement.personne.nom, p.analyse.prelevement.personne.prenom, p.analyse.idAnalyse , p.analyse.urgent , p.analyse.prelevement.typePrelevement.libelle "
				+ "FROM Puce p WHERE p.analyse.typeAnalyse.idTypeAnalyse = 3 AND p.idPuce = :idPuce ";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idPuce", idPuce);
		objects = (Object[]) query.uniqueResult();

		return objects;
	}

	@Override
	public Personne getPersonneByIpp(String ipp) {
		Personne personne = null;
		String sql = "SELECT  p FROM Personne p WHERE p.iPP = :iPP";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("iPP", ipp);
		List<Personne> personnes = (ArrayList<Personne>) findMany(query);
		if (personnes != null && personnes.size() > 0) {
			personne = personnes.get(0);
		}
		return personne;
	}

	@Override
	public String getNomPrenomFromIdAnalyse(Integer idAnalyse) {
		String sql = "SELECT distinct concat(concat(a.prelevement.personne.nom,' '), a.prelevement.personne.prenom) FROM Analyse a WHERE a.idAnalyse = :idAnalyse";
		Query query = HibernateUtil.getSession().createQuery(sql).setParameter("idAnalyse", idAnalyse);
		return (String)query.uniqueResult();
	}


}